<template>
  <div class="three-wrapper">
    <div class="box" ref="box"></div>
    <div class="actions"></div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass'

const clock = new THREE.Clock()
const FPS = 30
const renderT = 1 / FPS
let timeS = 0

export default {
  components: {},
  props: {},
  data() {
    return {
      el: null,
      scene: null,
      camera: null,
      renderer: null,
      controls: null,
      animationFrameId: null,
      composer: null,
      bloomPass: null,
      mesh: null,
      glowIntensity: 1.0,
      glowSpeed: 2.0,
      isGlowing: true
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {
    this.el = this.$refs['box']
    this.clock = new THREE.Clock()
    this.initThree()
  },
  activated() {},
  deactivated() {},
  updated() {},
  beforeDestroy() {
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId)
    }
    // 清理资源
    if (this.renderer) {
      this.renderer.dispose()
    }
  },
  destroyed() {},
  methods: {
    initThree() {
      this.initScene()
      this.initCamera()
      this.initRender()
      this.initLight()
      this.initControls()
      this.initPostProcessing()
      this.animate()
      this.scene.add(this.setGridHelper(100 * 2, 10 * 2))
      this.scene.add(this.setAxesHelper(100000))

      this.addMesh()
    },
    addMesh() {
      const geometry = new THREE.TorusGeometry(10, 1, 16, 100)
      const material = new THREE.MeshStandardMaterial({
        color: 0xffff00,
        transparent: true,
        emissive: 0xffff00, // 添加自发光颜色
        emissiveIntensity: 0.5 // 自发光强度
      })
      this.mesh = new THREE.Mesh(geometry, material)
      this.scene.add(this.mesh)
    },
    setGridHelper(size, divisions) {
      const gridHelper = new THREE.GridHelper(size, divisions)
      gridHelper.material.opacity = 0.6
      gridHelper.material.transparent = true
      return gridHelper
    },
    setAxesHelper(size) {
      return new THREE.AxesHelper(size)
    },
    initScene() {
      this.scene = new THREE.Scene()
    },
    initCamera() {
      const asp = this.el.offsetWidth / this.el.offsetHeight
      this.camera = new THREE.PerspectiveCamera(45, asp, 0.1, 10000000)
      this.camera.position.set(300, 300, 300)
      this.camera.lookAt(this.scene.position)
      this.scene.add(this.camera)
    },
    initRender(clearColor = '#000') {
      const width = this.el.offsetWidth
      const height = this.el.offsetHeight
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
      })
      this.renderer.setPixelRatio(window.devicePixelRatio)
      this.renderer.setSize(width, height)
      this.el.append(this.renderer.domElement)
    },
    initLight() {
      const ambientLight = new THREE.AmbientLight('#fff', 0.4)
      this.scene.add(ambientLight)
      const directionalLight = new THREE.DirectionalLight('#fff', 0.8)
      directionalLight.position.set(30, 30, 30).normalize()
      this.scene.add(directionalLight)
    },
    initControls() {
      this.controls = new OrbitControls(
        this.camera,
        this.renderer.domElement,
        {}
      )
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.05
    },
    // 初始化后期处理
    initPostProcessing() {
      // 创建效果组合器
      this.composer = new EffectComposer(this.renderer)

      // 添加渲染通道
      const renderPass = new RenderPass(this.scene, this.camera)
      this.composer.addPass(renderPass)

      // 添加辉光（Bloom）效果
      this.bloomPass = new UnrealBloomPass(
        new THREE.Vector2(this.el.offsetWidth, this.el.offsetHeight),
        1.0, // 强度 - 将在动画中动态调整
        0.4, // 半径
        0.85 // 阈值
      )
      this.composer.addPass(this.bloomPass)

      // 添加输出通道
      const outputPass = new OutputPass()
      this.composer.addPass(outputPass)
    },
    // 更新辉光效果
    updateGlowEffect() {
      if (!this.isGlowing || !this.bloomPass) return

      // 使用正弦函数创建平滑的闪烁效果
      const time = this.clock.getElapsedTime()
      const intensity = 0.5 + Math.sin(time * this.glowSpeed) * 0.5

      // 更新辉光强度
      this.bloomPass.strength = intensity * this.glowIntensity

      // 可选：同时更新材质的自发光强度
      if (this.mesh && this.mesh.material) {
        this.mesh.material.emissiveIntensity = 0.3 + intensity * 0.7
      }
    },
    render() {
      const dt = this.clock.getDelta()
      const T = clock.getDelta()
      timeS = timeS + T

      if (timeS > renderT) {
        this.controls.update(dt)
        this.updateGlowEffect() // 更新辉光效果

        // 使用后期处理组合器进行渲染
        this.composer.render()
        timeS = 0
      }
    },
    animate() {
      this.render()
      this.animationFrameId = requestAnimationFrame(this.animate)
    },
    // 控制辉光效果的方法
    startGlowing() {
      this.isGlowing = true
    },
    stopGlowing() {
      this.isGlowing = false
      // 重置辉光强度
      if (this.bloomPass) {
        this.bloomPass.strength = 0
      }
      if (this.mesh && this.mesh.material) {
        this.mesh.material.emissiveIntensity = 0
      }
    },
    setGlowSpeed(speed) {
      this.glowSpeed = speed
    },
    setGlowIntensity(intensity) {
      this.glowIntensity = intensity
    }
  },
  filters: {}
}
</script>

<style scoped lang="scss">
.three-wrapper {
  height: 100%;
  position: relative;
  .box {
    height: 100%;
    width: 100%;
    background: url(./images/map-bg.png);
    background-size: cover;
    background-repeat: no-repeat;
    overflow: hidden;
  }
  .actions {
    position: absolute;
    bottom: 10px;
    left: 10px;
    display: flex;
    gap: 10px;

    button {
      padding: 8px 16px;
      border: none;
      background-color: #409eff;
      color: #fff;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
      transition: all 0.3s ease;

      &:hover {
        background-color: #66b1ff;
        transform: translateY(-2px);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
      }
    }
  }
}
</style>
